package com.xiaomaoguai.fcp.pre.kepler.delay.task.redis.config;

import com.xiaomaoguai.fcp.pre.kepler.delay.task.DelayTaskMsg;
import com.xiaomaoguai.fcp.pre.kepler.delay.task.DelayTaskProducer;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;

/**
 * 基于redis的延迟任务实现
 *
 * @fileName: RedisDelayTaskProducer.java
 * @author: WeiHui
 * @date: 2019/2/13 13:51
 * @version: v1.0.0
 * @since JDK 1.8
 */
@Service
public class RedisDelayTaskProducer implements DelayTaskProducer {

	@Resource
	private RedisTemplate<?, ?> redisTemplate;

	@Resource(name = "redisTemplate")
	private ZSetOperations<String, Object> zSetOperations;

	/**
	 * 创建延迟任务
	 *
	 * @param taskName     任务名称
	 * @param taskData     任务数据
	 * @param delaySeconds 延迟多少秒
	 */
	@Override
	public void createDelayTask(String taskName, Object taskData, Long delaySeconds) {
		Assert.notNull(taskName, "消息类型不能为空");
		Assert.notNull(taskData, "消息体不能为空");
		Assert.notNull(delaySeconds, "延迟时间不能为空");
		DelayTaskMsg delayTaskMsg = new DelayTaskMsg(taskName, taskData);
		delayTaskMsg.setDelaySeconds(delaySeconds);
		//redis-key 前缀
		String redisKey = "DELAY_TASK_QUEUE_KEY";
		Long currentTimeMillis = currentTimeMillis() + delaySeconds * 1000L;
		zSetOperations.add(redisKey, delayTaskMsg, currentTimeMillis);
	}

	/**
	 * 统一通过redis的时间当做当前时间，防止多个服务器的时间不一致的问题
	 *
	 * @return 当前时间
	 */
	private Long currentTimeMillis() {
		return redisTemplate.execute(RedisServerCommands::time);
	}

}
